﻿// ## 2024/1/2 # 铃 # 汉化,优化,重构部分代码等等 ##
// ## 2021/10/24 # 江东新风 # 将pk::add_troops换成ch::add_troops以修正显示错误 ##
// ## 2021/01/06 #mess#修正乱码语句##
// ## 2020/11/20 #mess#修正乱码语句##
// ## 2020/10/30 #江东新风#同步马术书大神的更新##


namespace 部队战斗效果
{


    const bool 显示对话 = true;
    const int 对话显示概率 = 30;

    const bool 野战包围效果 = true;
    const bool 野战季节效果 = true;
    const bool 野战地形效果 = true;
    const bool 野战逃亡效果 = true;
    const bool 水流效果开关 = true;

    const bool 火势蔓延效果 = true;
    const int 火势蔓延概率 = 50;
    const bool 风向消息显示 = true;
    const bool 城市特产效果 = true;
    const bool 武将出身效果 = true;


    const bool 대화표시설정 = true;   // 야전부대 효과의 대화 표시 여부 설정
    const int  대화표시확률 = 30;     // 야전부대 효과의 상시대화 확률 설정

    const bool 야전포위효과 = true;   // 포위당한 부대는 매턴 기력 감소
    const bool 야전계절효과 = true;   // 계절에 따라 부대기력 감소
    const bool 야전지형설정 = true;   // 지형에 따라 부대기력 감소
    const bool 야전탈영설정 = true;   // 기력 저조 부대 병력 감소 적용
    const bool 수상부대휩쓸림 = true;  // 수상부대 휩쓸림 효과 적용


    const bool 화계확산효과 = true;    // 매턴 바람방향에 따른 화계 확산 효과
    const int  화계확산확률 = 50;


    const bool 풍향메세지표시 = true;

    const bool 도시특산효과 = true;    // 부대병과가 소속도시의 특산병종과 일치하면 부대기력 증가
    const bool 무장출신주효과 = true;   // 무장의 출신(주)와 소속도시의 주 일치 시 부대기력 증가



    //---------------------------------------------------------------------------------------

    class Main
    {

        Main()
        {
            pk::bind(103, pk::trigger103_t(onGameInit));
            pk::bind(107, pk::trigger107_t(onNewDay));
            pk::bind(120, pk::trigger120_t(onDrawGame));
            pk::bind(174, pk::trigger174_t(action_done));
        }

        void onNewDay()
        {
            if (pk::is_campaign())
                return;

            if (pk::get_elapsed_days() <= 0)
                return;

            auto list = pk::list_to_array(pk::get_unit_list());
            for (int i = 0; i < int(list.length); i++)
            {
                pk::unit @unit = list[i];
                pk::point pos = unit.get_pos();
                pk::hex @hex = pk::get_hex(pos);

                野战包围(unit, pos, hex, 野战包围效果);
                季节影响(unit, pos, hex, 野战季节效果);
                地形影响(unit, pos, hex, 野战地形效果);
                士兵逃亡(unit, pos, hex, 野战逃亡效果);


                //地区特色效果(unit, pos, 城市特产效果);
                兵种家乡增强效果(unit, pos, 武将出身效果);
            }

            func_火势蔓延效果(火势蔓延效果);
        }

        bool wind_init;
        int wind_dir;

        void onDrawGame()
        {
            if (pk::is_campaign())
                return;
            if (火势蔓延效果)
            {
                string wind_name = get_wind_name(wind_dir);
                pk::draw_text(pk::encode(wind_name), pk::point(250, 45), 0xffffffff, FONT_BIG, 0xff000000);
            }
        }

        void action_done(pk::unit @unit, int type)
        {
            水流效果(unit, 水流效果开关);
        }


        void onGameInit()
        {
            if (pk::is_campaign())
                return;

            main.wind_init = true;
            main.wind_dir = pk::rand(方向_末);

            // show_log_wind_dir(wind_dir);
        }

        void 野战包围(pk::unit @unit, pk::point pos, pk::hex @hex, bool 是否应用)
        {
            if (是否应用)
            {

                int cnt_enemy = 0;
                array<pk::point> arr = pk::range(pos, 1, 1);
                for (int j = 0; j < int(arr.length); j++)
                {
                    pk::unit @target_unit = pk::get_unit(arr[j]);
                    if (target_unit !is null and pk::is_enemy(unit, target_unit))
                    {
                        cnt_enemy += 1;
                    }
                }
                if ((cnt_enemy >= 3) and !unit.has_skill(特技_血路))
                {
                    pk::add_energy(unit, -(2 + cnt_enemy), true);

                    if (显示对话 and pk::is_in_screen(pos))
                        pk::say(pk::encode("快突围"), pk::get_person(unit.leader));
                }
            }
        }

        //---------------------------------------------------------------------------------------

        void 季节影响(pk::unit @unit, pk::point pos, pk::hex @hex, bool 是否应用)
        {
            int energy_damage = -1;

            if (是否应用)
            {

                int unit_tekisei = pk::get_tekisei(unit);
                switch (pk::get_season())
                {
                    case 季节_夏:
                        energy_damage = energy_damage + unit_tekisei - 适性_A - 1;

                        if (显示对话 and pk::rand_bool(对话显示概率) and pk::is_in_screen(pos))
                        {
                            switch (pk::rand(4))
                            {
                                case 0:
                                    pk::say(pk::encode("酷暑难当,士兵们都很疲劳."), pk::get_person(unit.leader));
                                    break;
                                case 1:
                                    pk::say(pk::encode("很多士兵都中暑了"), pk::get_person(unit.leader));
                                    break;
                                case 2:
                                    pk::say(pk::encode("好猛烈的阳光"), pk::get_person(unit.leader));
                                    break;
                                case 3:
                                    pk::say(pk::encode("口干舌燥"), pk::get_person(unit.leader));
                                    break;
                            }
                        }
                        break;

                    case 季节_冬:
                        energy_damage = energy_damage + unit_tekisei - 适性_S - 1;

                        if (显示对话 and pk::rand_bool(对话显示概率) and pk::is_in_screen(pos))
                        {
                            switch (pk::rand(4))
                            {
                                case 0:
                                    pk::say(pk::encode("如此严寒, 士兵们扛不住了..."), pk::get_person(unit.leader));
                                    break;
                                case 1:
                                    pk::say(pk::encode("好冷呀..."), pk::get_person(unit.leader));
                                    break;
                                case 2:
                                    pk::say(pk::encode("寒风凛冽"), pk::get_person(unit.leader));
                                    break;
                                case 3:
                                    pk::say(pk::encode("要冻死了..."), pk::get_person(unit.leader));
                                    break;
                            }
                        }
                        break;
                }
            }

            pk::add_energy(unit, energy_damage, true);
        }

        //---------------------------------------------------------------------------------------
        void 地形影响(pk::unit @unit, pk::point pos, pk::hex @hex, bool 是否应用)
        {
            if (是否应用)
            {
                if (hex.terrain == 地形_崖)
                {
                    if (显示对话 and pk::is_in_screen(pos))
                    {
                        switch (pk::rand(4))
                        {
                            case 0:
                                pk::say(pk::encode("过了这道坎就行"), pk::get_person(unit.leader));
                                break;
                            case 1:
                                pk::say(pk::encode("行军太久,士兵们都很疲惫了"), pk::get_person(unit.leader));
                                break;
                            case 2:
                                pk::say(pk::encode("步子太慢了,我们加快速度"), pk::get_person(unit.leader));
                                break;
                            case 3:
                                pk::say(pk::encode("高地就在眼前了"), pk::get_person(unit.leader));
                                break;
                        }
                    }

                    pk::add_energy(unit, -2, true);
                }
            }
        }


        void 士兵逃亡(pk::unit @unit, pk::point pos, pk::hex @hex, bool 是否应用)
        {
            if (是否应用)
            {

                uint troops_loss = 0;

                if (unit.status == 部队状态_混乱)
                {
                    troops_loss = int(pk::min(unit.troops, pk::max(100.f, unit.troops * 0.05f)));
                    ch::add_troops(unit, -troops_loss, true, 102);

                    if (显示对话 and pk::is_in_screen(pos))
                    {
                        switch (pk::rand(4))
                        {
                            case 0:
                                pk::say(pk::encode("要尽快拨乱反正"), pk::get_person(unit.leader));
                                break;
                            case 1:
                                pk::say(pk::encode("士兵正在逃走"), pk::get_person(unit.leader));
                                break;
                            case 2:
                                pk::say(pk::encode("快把部队整合起来"), pk::get_person(unit.leader));
                                break;
                            case 3:
                                pk::say(pk::encode("照这样下去要全军覆没了"), pk::get_person(unit.leader));
                                break;
                        }
                    }
                }

                if (unit.energy <= 25)
                {
                    if (unit.energy <= 10)
                    {
                        troops_loss = int(pk::min(unit.troops, pk::max(10.f, unit.troops * 0.05f)));
                        ch::add_troops(unit, -troops_loss, true, 102);
                    }
                    else if (unit.energy <= 25)
                    {
                        troops_loss = int(pk::min(unit.troops, pk::max(10.f, unit.troops * 0.02f)));
                        ch::add_troops(unit, -troops_loss, true, 102);
                    }

                    if (显示对话 and pk::is_in_screen(pos))
                    {
                        switch (pk::rand(4))
                        {
                            case 0:
                                pk::say(pk::encode("逃兵层出不穷"), pk::get_person(unit.leader));
                                break;
                            case 1:
                                pk::say(pk::encode("士兵正在逃走"), pk::get_person(unit.leader));
                                break;
                            case 2:
                                pk::say(pk::encode("部队士气低落"), pk::get_person(unit.leader));
                                break;
                            case 3:
                                pk::say(pk::encode("照这样下去要全军覆没了"), pk::get_person(unit.leader));
                                break;
                        }
                    }
                }
                if (unit.troops == 0)
                    pk::kill(unit);
            }
        }

        //---------------------------------------------------------------------------------------

        void 水流效果(pk::unit @unit, bool 是否应用)
        {
            array<pk::point> steps;
            pk::point pos = unit.get_pos();
            pk::hex @hex = pk::get_hex(unit.get_pos());

            if (是否应用 and pk::is_in_water(unit) and (unit.is_player() or pk::is_in_screen(pos)) and unit.stock[10].amount != 3)
            {
                int dir_water = hex.direction;
                int dir_unit = unit.direction;
                int 是否顺流 = 0;

                switch (dir_unit)
                {
                    case 方向_西北:
                        if (dir_water == 方向_西北)
                            是否顺流 = 0;
                        else if (dir_water == 方向_北 or dir_water == 方向_西南)
                            是否顺流 = 1;
                        else if (dir_water == 方向_东北 or dir_water == 方向_南)
                            是否顺流 = 2;
                        else if (dir_water == 方向_东南)
                            是否顺流 = 3;
                        break;

                    case 方向_北:
                        if (dir_water == 方向_北)
                            是否顺流 = 0;
                        else if (dir_water == 方向_西北 or dir_water == 方向_东北)
                            是否顺流 = 1;
                        else if (dir_water == 方向_西南 or dir_water == 方向_东南)
                            是否顺流 = 2;
                        else if (dir_water == 方向_南)
                            是否顺流 = 3;
                        break;

                    case 方向_东北:
                        if (dir_water == 方向_东北)
                            是否顺流 = 0;
                        else if (dir_water == 方向_北 or dir_water == 方向_东南)
                            是否顺流 = 1;
                        else if (dir_water == 方向_西北 or dir_water == 方向_南)
                            是否顺流 = 2;
                        else if (dir_water == 方向_西南)
                            是否顺流 = 3;
                        break;

                    case 方向_西南:
                        if (dir_water == 方向_西南)
                            是否顺流 = 0;
                        else if (dir_water == 方向_西北 or dir_water == 方向_南)
                            是否顺流 = 1;
                        else if (dir_water == 方向_北 or dir_water == 方向_东南)
                            是否顺流 = 2;
                        else if (dir_water == 方向_东北)
                            是否顺流 = 3;
                        break;

                    case 方向_南:
                        if (dir_water == 方向_南)
                            是否顺流 = 0;
                        else if (dir_water == 方向_西南 or dir_water == 方向_东南)
                            是否顺流 = 1;
                        else if (dir_water == 方向_西北 or dir_water == 方向_东北)
                            是否顺流 = 2;
                        else if (dir_water == 方向_北)
                            是否顺流 = 3;
                        break;

                    case 方向_东南:
                        if (dir_water == 方向_东南)
                            是否顺流 = 0;
                        else if (dir_water == 方向_南 or dir_water == 方向_东北)
                            是否顺流 = 1;
                        else if (dir_water == 方向_西南 or dir_water == 方向_北)
                            是否顺流 = 2;
                        else if (dir_water == 方向_西北)
                            是否顺流 = 3;
                        break;
                }

                int n = 2;
                //长江主干
                int city_id = pk::get_city_id(pos);
                if (city_id == 铃据点_江陵 or city_id == 铃据点_巴东 or city_id == 铃据点_江夏 or city_id == 铃据点_柴桑) n = 3;

                //黄河上游
                if (city_id == 铃据点_长安 or city_id == 铃据点_洛阳 or city_id == 铃据点_河东) n = 3;

                //长江上游.嘉陵江
                if (city_id == 铃据点_成都 or city_id == 铃据点_梓潼) n = 3;

                //珠江水系
                if (city_id == 铃据点_合浦) n = 3;

                //淮河等其他水系
                else n = 2;


                //顺流的情况,固定走2格
                if (是否顺流 <= 1)
                {
                    if (unit.weapon == 兵器_楼船) n = int(n / 2 - 0.5);
                    if (unit.weapon == 兵器_斗舰) n = 0;

                    for (int j = 0; j < n; j++)
                    {

                        if (!pk::is_valid_hex_direction(dir_water))
                            break;
                        pos = pk::get_neighbor_pos(pos, dir_water);
                        @hex = pk::get_hex(pos);
                        if (!pk::is_valid_pos(pos) || hex.has_unit || hex.has_building || !pk::is_water_terrain(hex.terrain) || !cast<pk::func169_t @>(pk::get_func(169))(unit, hex.terrain))
                            break;
                      //  pk::trace(pk::format("部队方向{},水系方向{},顺流系数{},x{},y{}", dir_unit, dir_water, 是否顺流, pos.x, pos.y));
                        steps.insertLast(pos);
                    }
                }

                //逆流的情况,要取决于适性
                if (是否顺流 >= 2)
                {
                    if (unit.type == 部队类型_运输) n = 2;
                    else   n = int(2.0 - pk::get_tekisei(unit) * 0.5);
                    if (!unit.is_player()) n = n / 3;

                    if (unit.weapon == 兵器_楼船) n /= 2;
                    if (unit.weapon == 兵器_斗舰) n = 0;

                    n = pk::max(n, 0);
                    n = pk::min(n, 2);

                    if (ch::has_skill(unit, 特技_水师)) n = 0;

                    for (int j = 0; j < n; j++)
                    {

                        if (!pk::is_valid_hex_direction(dir_water))
                            break;
                        pos = pk::get_neighbor_pos(pos, dir_water);
                        @hex = pk::get_hex(pos);
                        if (!pk::is_valid_pos(pos) || hex.has_unit || hex.has_building || !pk::is_water_terrain(hex.terrain) || !cast<pk::func169_t @>(pk::get_func(169))(unit, hex.terrain))
                            break;
                        steps.insertLast(pos);
                        //pk::trace(pk::format("部队方向{},水系方向{},顺流系数{},x{},y{}", dir_unit, dir_water, 是否顺流, pos.x, pos.y));
                    }
                }

               //pk::trace(pk::format("部队方向{},水系方向{},顺流系数{},n{}", dir_unit, dir_water, 是否顺流, n));



                if (steps.length != 0)
                {
                    //顺流
                    if (显示对话 and pk::is_in_screen(pos) and 是否顺流 <= 1)
                    {
                        switch (pk::rand(8))
                        {
                            case 0:
                                pk::say(pk::encode("顺流而下!"), pk::get_person(unit.leader));
                                break;
                            case 1:
                                pk::say(pk::encode("顺水推舟!"), pk::get_person(unit.leader));
                                break;
                            case 2:
                                pk::say(pk::encode("借助水流行军!"), pk::get_person(unit.leader));
                                break;
                            case 3:
                                pk::say(pk::encode("认真利用水流!"), pk::get_person(unit.leader));
                                break;
                        }
                    }

                    if (显示对话 and pk::is_in_screen(pos) and 是否顺流 > 1)
                    {
                        //逆流
                        switch (pk::rand(6))
                        {
                            case 0:
                                pk::say(pk::encode("看清楚水流方向!"), pk::get_person(unit.leader));
                                break;
                            case 1:
                                pk::say(pk::encode("看清楚水流方向!"), pk::get_person(unit.leader));
                                break;
                            case 2:
                                pk::say(pk::encode("水流湍急!"), pk::get_person(unit.leader));
                                break;
                            case 3:
                                pk::say(pk::encode("被水冲走了!"), pk::get_person(unit.leader));
                                break;
                        }
                    }

                    pk::move(unit, steps);
                   // pk::set_pos(unit, steps[0]);
                }
            }
        }



//---------------------------------------------------------------------------------------
        void func_火势蔓延效果(bool 是否应用)
        {
            if (是否应用)
            {
                pk::array<pk::point> arr_fire;

                if (wind_init)
                    wind_init = false;
                else if (pk::get_day() == 1 and pk::is_first_month_of_quarter(pk::get_month()))
                    main.wind_dir = pk::rand(方向_末);
                else
                    main.wind_dir = get_wind_dir(main.wind_dir);

                int fire_dir = pk::get_opposite_direction(main.wind_dir);
                for (int pos_x = 0; pos_x < 200; pos_x++)
                {
                    for (int pos_y = 0; pos_y < 200; pos_y++)
                    {
                        pk::point pos;
                        pos.x = pos_x;
                        pos.y = pos_y;

                        pk::hex @hex = pk::get_hex(pos);
                        if (pk::is_valid_pos(pos) and pk::is_valid_hex_direction(fire_dir) and pk::is_on_fire(pos) and !contains_pos(arr_fire, pos))
                        {
                            pk::point neighbor_pos = pk::get_neighbor_pos(pos, fire_dir);
                            if (pk::is_valid_pos(neighbor_pos))
                            {
                                pk::hex @neighbor_hex = pk::get_hex(neighbor_pos);
                                int terrain_id = neighbor_hex.terrain;

                                if (pk::rand_bool(火势蔓延概率) and pk::is_enabled_terrain(terrain_id))
                                {
                                    if (!pk::is_water_terrain(terrain_id) or (pk::is_water_terrain(terrain_id) and neighbor_hex.has_unit))
                                    {
                                        arr_fire.insertLast(neighbor_pos);
                                        pk::create_fire(neighbor_pos, (1 + pk::rand(2)));

                                        pk::unit @unit = pk::get_unit(neighbor_pos);
                                        if (unit !is null and pk::is_in_screen(neighbor_pos))
                                        {
                                            switch (pk::rand(4))
                                            {
                                                case 0:
                                                    pk::say(pk::encode("别慌张!"), pk::get_person(unit.leader));
                                                    break;
                                                case 1:
                                                    pk::say(pk::encode("快把火扑灭"), pk::get_person(unit.leader));
                                                    break;
                                                case 2:
                                                    pk::say(pk::encode("别让火点着了"), pk::get_person(unit.leader));
                                                    break;
                                                case 3:
                                                    pk::say(pk::encode("该离开这里了"), pk::get_person(unit.leader));
                                                    break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        int get_wind_dir(int seed_dir)
        {
            int new_dir;
            int rand_dir = pk::rand(5);

            switch (seed_dir)
            {
                case 方向_西北:
                    switch (rand_dir)
                    {
                        case 0:
                            new_dir = 方向_西南;
                            break;
                        case 1:
                            new_dir = 方向_西南;
                            break;
                        case 2:
                            new_dir = 方向_西北;
                            break;
                        case 3:
                            new_dir = 方向_北;
                            break;
                        case 4:
                            new_dir = 方向_北;
                            break;
                    }
                    break;

                case 方向_北:
                    switch (rand_dir)
                    {
                        case 0:
                            new_dir = 方向_西北;
                            break;
                        case 1:
                            new_dir = 方向_西北;
                            break;
                        case 2:
                            new_dir = 方向_北;
                            break;
                        case 3:
                            new_dir = 方向_东北;
                            break;
                        case 4:
                            new_dir = 方向_东北;
                            break;
                    }
                    break;

                case 方向_东北:
                    switch (rand_dir)
                    {
                        case 0:
                            new_dir = 方向_北;
                            break;
                        case 1:
                            new_dir = 方向_北;
                            break;
                        case 2:
                            new_dir = 方向_东北;
                            break;
                        case 3:
                            new_dir = 方向_东南;
                            break;
                        case 4:
                            new_dir = 方向_东南;
                            break;
                    }
                    break;

                case 方向_西南:
                    switch (rand_dir)
                    {
                        case 0:
                            new_dir = 方向_南;
                            break;
                        case 1:
                            new_dir = 方向_南;
                            break;
                        case 2:
                            new_dir = 方向_西南;
                            break;
                        case 3:
                            new_dir = 方向_西北;
                            break;
                        case 4:
                            new_dir = 方向_西北;
                            break;
                    }
                    break;

                case 方向_南:
                    switch (rand_dir)
                    {
                        case 0:
                            new_dir = 方向_东南;
                            break;
                        case 1:
                            new_dir = 方向_东南;
                            break;
                        case 2:
                            new_dir = 方向_南;
                            break;
                        case 3:
                            new_dir = 方向_西南;
                            break;
                        case 4:
                            new_dir = 方向_西南;
                            break;
                    }
                    break;

                case 方向_东南:
                    switch (rand_dir)
                    {
                        case 0:
                            new_dir = 方向_东北;
                            break;
                        case 1:
                            new_dir = 方向_东北;
                            break;
                        case 2:
                            new_dir = 方向_东南;
                            break;
                        case 3:
                            new_dir = 方向_南;
                            break;
                        case 4:
                            new_dir = 方向_南;
                            break;
                    }
                    break;
            }

            return new_dir;
        }

        void show_log_wind_dir(int direction)
        {
            string wind_name = get_wind_name(direction);

            int pause = int(pk::option["MessagePause"]);
            pk::option["MessagePause"] = 5;
            switch (pk::rand(4))
            {
                case 0:
                    pk::message_box(pk::encode(pk::format("据候风铜鸟所示,此地应有\x1b[1x{}\x1b[0x.", wind_name)), pk::get_person(무장_좌자));
                    break;
                case 1:
                    pk::message_box(pk::encode(pk::format("观此间云色,将有\x1b[1x{}\x1b[0x来.", wind_name)), pk::get_person(무장_관로));
                    break;
                case 2:
                    pk::message_box(pk::encode(pk::format("观此卦相,此地当有\x1b[1x{}\x1b[0x.", wind_name)), pk::get_person(무장_허소));
                    break;
                case 3:
                    pk::message_box(pk::encode(pk::format("我夜观天象,明日应有\x1b[1x{}\x1b[0x.", wind_name)), pk::get_person(무장_예형));
                    break;
            }
            pk::option["MessagePause"] = pause;
        }


        string get_wind_name(int direction)
        {
            string wind_name;
            switch (direction)
            {
                case 方向_西北:
                    wind_name = "西北风";
                    break;
                case 方向_北:
                    wind_name = "北风";
                    break;
                case 方向_东北:
                    wind_name = "东北风";
                    break;
                case 方向_西南:
                    wind_name = "西南风";
                    break;
                case 方向_南:
                    wind_name = "南风";
                    break;
                case 方向_东南:
                    wind_name = "东南风";
                    break;
            }
            return wind_name;
        }

        bool contains_pos(pk::array<pk::point> arr_pos, pk::point pos)
        {
            for (int i = 0; i < int(arr_pos.length); i++)
            {
                if (pos == arr_pos[i])
                    return true;
            }

            return false;
        }

        //---------------------------------------------------------------------------------------

        void 地区特色效果(pk::unit @unit, pk::point pos, bool 是否应用)
        {
            if (!pk::is_normal_force(unit.get_force_id()))
                return;

            if (是否应用)
            {
                pk::city @city = pk::get_city(pk::get_service(unit));
                if (pk::is_alive(city))
                {
                    int weapon_heishu = pk::equipment_id_to_heishu(unit.weapon);

                    if (pk::is_large_city(city) and unit.type == 部队类型_战斗 and unit.troops < 3000)
                    {
                        ch::add_troops(unit, int(0.05f * unit.troops), true);
                    }
                    if (city.tokusan[weapon_heishu] and unit.energy < 40)
                    {
                        if (显示对话 and pk::rand_bool(对话显示概率) and pk::is_in_screen(pos)) // 화면 안 부대만 대화 표시
                        {
                            string city_name = pk::decode(pk::get_name(city));
                            string weapon_name = get_weapon_name(unit.weapon);

                            switch (pk::rand(4))
                            {
                                case 0:
                                    pk::say(pk::encode(pk::format("这就是\x1b[2x{} \x1b[1x{}\x1b[0x的气势!", city_name, weapon_name)), pk::get_person(unit.leader));
                                    break;
                                case 1:
                                    pk::say(pk::encode(pk::format("展示下\x1b[2x{} \x1b[1x{}\x1b[0x的威力!", city_name, weapon_name)), pk::get_person(unit.leader));
                                    break;
                                case 2:
                                    pk::say(pk::encode(pk::format("\x1b[2x{}自古以\x1b[1x{}\x1b[0x闻名!", city_name, weapon_name)), pk::get_person(unit.leader));
                                    break;
                                case 3:
                                    pk::say(pk::encode(pk::format("\x1b[2x{}\x1b[1x{}\x1b[0x威名赫赫!", city_name, weapon_name)), pk::get_person(unit.leader));
                                    break;
                            }
                        }

                        pk::add_energy(unit, +5, true);
                    }
                }
            }
        }

        string get_weapon_name(int weapon_id)
        {
            string weapon_name;
            switch (weapon_id)
            {
                case 兵器_剑:
                    weapon_name = "剑兵";
                    break;
                case 兵器_枪:
                    weapon_name = "枪兵";
                    break;
                case 兵器_戟:
                    weapon_name = "戟兵";
                    break;
                case 兵器_弩:
                    weapon_name = "弩兵";
                    break;
                case 兵器_战马:
                    weapon_name = "骑兵";
                    break;
                case 兵器_冲车:
                    weapon_name = "冲车";
                    break;
                case 兵器_井阑:
                    weapon_name = "井阑";
                    break;
                case 兵器_投石:
                    weapon_name = "投石";
                    break;
                case 兵器_木兽:
                    weapon_name = "木兽";
                    break;
                case 兵器_走舸:
                    weapon_name = "水军";
                    break;
                case 兵器_楼船:
                    weapon_name = "水军";
                    break;
                case 兵器_斗舰:
                    weapon_name = "水军";
                    break;
                default:
                    weapon_name = "??";
                    break;
            }
            return weapon_name;
        }

        //---------------------------------------------------------------------------------------

        void 兵种家乡增强效果(pk::unit @unit, pk::point pos, bool 是否应用)
        {
            if (!pk::is_normal_force(unit.get_force_id()))
                return;

            if (是否应用)
            {
                pk::person @leader = pk::get_person(unit.leader);
                int birth_province = leader.birthplace;

                pk::building @building = pk::get_building(pk::get_service(unit));
                if (!pk::is_alive(building))
                    return;

                pk::city @service_city = pk::get_city(pk::get_city_id(building.pos));
                int service_province = service_city.province;

                if (birth_province == service_province)
                {
                    if (显示对话 and pk::rand_bool(对话显示概率) and pk::is_in_screen(pos))
                    {
                        string service_province_name = pk::decode(pk::get_name(pk::get_province(service_province)));

                        switch (pk::rand(4))
                        {
                            case 0:
                                pk::say(pk::encode(pk::format("\x1b[1x{}兵\x1b[0x,随我来", service_province_name)), pk::get_person(unit.leader));
                                break;
                            case 1:
                                pk::say(pk::encode(pk::format("由我来率领这批精锐的\x1b[1x{}兵\x1b[0x吧", service_province_name)), pk::get_person(unit.leader));
                                break;
                            case 2:
                                pk::say(pk::encode(pk::format("就让\x1b[1x{}兵\x1b[0x在这场战斗中扬名立万吧", service_province_name)), pk::get_person(unit.leader));
                                break;
                            case 3:
                                pk::say(pk::encode(pk::format("展示\x1b[1x{}兵\x1b[0x的战力吧", service_province_name)), pk::get_person(unit.leader));
                                break;
                        }
                    }

                    pk::add_energy(unit, +5, true);
                }
            }
        }

        //---------------------------------------------------------------------------------------

    }

    Main main;
}